package edu.hit.pact.pgse.client.handler;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.mina.core.future.ConnectFuture;
import org.apache.mina.core.service.IoConnector;
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSession;

import edu.hit.pact.pgse.bean.TaskPieceStatistics;
import edu.hit.pact.pgse.client.ClientMainControl;
import edu.hit.pact.pgse.client.ClientManager;
import edu.hit.pact.pgse.communication.message.TaskPieceStatisticsMessage;
import edu.hit.pact.pgse.crawler.util.SleepThread;

public class ClientMasterHandler extends IoHandlerAdapter{
	private Log logger;
	private ClientManager clientManager;
	
	public ClientMasterHandler(ClientManager clientManager){
		this.logger = LogFactory.getLog(ClientMasterHandler.class);
		this.clientManager = clientManager;
		System.out.println("handler is created");
	}
	/*
	 * (non-Javadoc)
	 * @see org.apache.mina.core.service.IoHandlerAdapter#sessionOpened(org.apache.mina.core.session.IoSession)
	 */
	public void sessionOpened(IoSession session) {
		logger.error("session open");
		clientManager.setMasterSession(session);
	}//end for
	
    public void sessionCreated(IoSession session) {
    	// set idle time to MAX_IDLE_TIME seconds
    	System.out.println("session created");
    }
    
    /*
     * (non-Javadoc)
     * @see org.apache.mina.core.service.IoHandlerAdapter#messageReceived(org.apache.mina.core.session.IoSession, java.lang.Object)
     */
    @Override
    public void messageReceived(IoSession session, Object message) {
    	if (!(message instanceof TaskPieceStatisticsMessage)){
    		logger.error("client recived a error message from master!");
    	}
    	logger.info("clientManager processFinishedNotify");
    	TaskPieceStatistics statistics = ((TaskPieceStatisticsMessage)message).getStatistics();
    	clientManager.processFinishedNotify(statistics);
    }
	
    /*
     * (non-Javadoc)
     * @see org.apache.mina.core.service.IoHandlerAdapter#sessionIdle(org.apache.mina.core.session.IoSession, org.apache.mina.core.session.IdleStatus)
     */
	public void sessionIdle(IoSession session, IdleStatus status) {
		logger.info("is idle, do nothing");
	}
    
	@Override
	public void sessionClosed(IoSession session) throws Exception {
		logger.error("session is closed normally");
		session.close(true);
        logger.error("after closing, the address is "+ session.getRemoteAddress());
//        reConnect(session);
	}
	
	/*
	 * (non-Javadoc)
	 * @see org.apache.mina.core.service.IoHandlerAdapter#exceptionCaught(org.apache.mina.core.session.IoSession, java.lang.Throwable)
	 */
    @Override
    public void exceptionCaught(IoSession session, Throwable cause) {
        logger.error("Unexpected exception.", cause);
        // Close connection when unexpected exception is caught.
        session.close(true);
    }
    
    public boolean reConnect(IoSession session){
    	IoConnector connector = (IoConnector) session.getService();
    	for(int i=0; i<3; i++){
            try {
                ConnectFuture future = connector.connect(session.getRemoteAddress());
                future.join();
                clientManager.setMasterSession(future.getSession());
                return true;
            } catch (RuntimeException e) {
                logger.error("Failed to connect.");
                SleepThread.sleep(5000);
            }
        }
    	return false;
    }
}
